From 2b87d5adbbe9df8fe4756da4f40a84504b6acf2e Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Tue, 28 Nov 2006 13:46:10 +0000 Subject: [PATCH] [QEMU] pci: Unaligned config read/write overflow The default config read/write handlers allows a 4-byte read/write at address 255. This can clobber the field after the config area. This happens to be the PCIBus pointer in the PCIDevice structure. This patch stops this from reducing the read/write to the (largest multiple of 2) number of bytes within the config area. Signed-off-by: Herbert Xu --- tools/ioemu/hw/pci.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/tools/ioemu/hw/pci.c b/tools/ioemu/hw/pci.c index 77737c8615..cea81f7b7f 100644 --- a/tools/ioemu/hw/pci.c +++ b/tools/ioemu/hw/pci.c @@ -221,16 +221,23 @@ uint32_t pci_default_read_config(PCIDevice *d, uint32_t address, int len) { uint32_t val; + switch(len) { - case 1: - val = d->config[address]; - break; - case 2: - val = le16_to_cpu(*(uint16_t *)(d->config + address)); - break; default: case 4: - val = le32_to_cpu(*(uint32_t *)(d->config + address)); + if (address <= 0xfc) { + val = le32_to_cpu(*(uint32_t *)(d->config + address)); + break; + } + /* fall through */ + case 2: + if (address <= 0xfe) { + val = le16_to_cpu(*(uint16_t *)(d->config + address)); + break; + } + /* fall through */ + case 1: + val = d->config[address]; break; } return val; @@ -333,7 +340,8 @@ void pci_default_write_config(PCIDevice *d, d->config[addr] = val; } - addr++; + if (++addr > 0xff) + break; val >>= 8; } -- 2.30.2